﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Linq;
using $prjsn$.Common;
using StructureMap;

using ProjectBase.Core;
using ProjectBase.Core.Service;
using StructureMap.Query;

namespace $safeprojectname$.IoC
{
    [CLSCompliant(false)]
    public partial class StructureMapFactoryProvider : IFactoryProvider
    {
        //private static readonly IContainer Profile2;

        #region static FactoryProvider Init

        static StructureMapFactoryProvider()
        {
            ObjectFactory.Initialize(x =>
            {
                x.UseDefaultStructureMapConfigFile = false;
                // Defaults
                x.IncludeRegistry<DefaultProfileRegistry>();
            });

            ObjectFactory.Container.SetDefaultsToProfile(DefaultProfileRegistry.ProfileName);

            // TODO Profile 2
            //Profile2 = new StructureMap.Container(new Profile2Registry());
            //Profile2.SetDefaultsToProfile(Profile2Registry.ProfileName);
        }

        public static void ResetDefaults()
        {
            ObjectFactory.ResetDefaults();
            ObjectFactory.Container.SetDefaultsToProfile(DefaultProfileRegistry.ProfileName);

            // TODO Profile 2
            //Profile2.SetDefaultsToProfile(Profile2Registry.ProfileName);
        }

        #endregion static FactoryProvider Init

        #region static internal

        internal static IDictionary<string, Type> GetPluginTypes(Func<IPluginTypeConfiguration, bool> action)
        {
            return ObjectFactory.Model.PluginTypes
                .Where(action)
                .Select(t => t.PluginType)
                .ToDictionary(t => t.Name.ToLowerInvariant()
                , t => t
                , StringComparer.InvariantCultureIgnoreCase);
        }

        #endregion static internal

        #region IFactoryProvider Members

        public virtual object GetService(Type serviceType)
        {
            return CreateInstance(serviceType);
        }

        public virtual T CreateInstance<T>(Type implementor = null)
            where T : class, IService
        {
            return CreateInstance(typeof(T), implementor) as T;
        }

        public virtual object CreateInstance(Type type, Type implementor = null)
        {
            object instance;
            if (!SecurityManager.IsInitialized)
            {
                instance = ObjectFactory.GetInstance(implementor ?? type);
                return instance;
            }

            //if (Profile2 should be used)
            //{
            //    instance = ObjectFactory.GetInstance(implementor ?? type);
            //    return instance;
            //}

            instance = ObjectFactory.GetInstance(implementor ?? type);
            return instance;
        }

        public virtual IEnumerable<T> CreateInstances<T>()
            where T : class, IService
        {
            return ObjectFactory.GetAllInstances<T>();
        }

        /// <summary>
        ///     Injects dependencies via setters. Intended for 'external framework' created instances, e.g. aspx Page
        /// </summary>
        public virtual void Enrich<T>(T instance)
        {
            ObjectFactory.BuildUp(instance);
        }

        #endregion IFactoryProvider Members
    }
}